
var sid_items="1234567890qwertyuiopasdfghjklzxcvbnm";

/**
 * Class: LNSessions
 *		User sessions tracker
 */

/**
 * Method: Constructor
 * 
 */
function LNSessions()
{

}

/**
 * Method: mk_sid
 *		Generates a random seed for HTTP cookie
 * 
 */
LNSessions.prototype.mk_sid=function() {
	var r="";
	for (var i=0;i<48;i++) {
		r+=sid_items.substr(Math.floor(Math.random()*sid_items.length),1);
	}
	return r;
}

/**
 * Method: load_roles
 *		Fetches user session roles from database
 *
 * Parameters:
 *		rr typeof LNRR - request-response object
 */
LNSessions.prototype.load_roles=function(rr)
{
	if (rr.user.calc_no_roles==1) return;
	var arr=rr.site.sql.execute_and_fetch("sessions/roles",{user_id:rr.uid});
	for (var i=0,s=arr.length;i<s;i++) {
		var x=arr[i];
		rr.roles[x.code]=1;
		rr.role_ids[x.id]=1;
	}
}

/**
 * Method: login_auth
 *		Performs user auth by login, creates cookie and also removes expired sessions from database
 *
 * Parameters:
 *		rr typeof LNRR - request-response object
 *
 * Returns:
 *		error code or null
 */
LNSessions.prototype.login_auth=function(rr) {
	var r=rr.site.sql.execute_and_fetch_one('sessions/auth_user',rr.fields);
	if (!r) {
		if (rr.site.auth && rr.site.auth.onerror) rr.site.auth.onerror(rr);
		return "no_user";
	}
	this.force_auth(rr,r.id);
	return null;
}

/**
 * Method: force_auth
 *
 */
LNSessions.prototype.force_auth=function(rr,user_id) {
	rr.uid=user_id;
//	rr.user=rr.site.sql.execute_and_fetch_one('sessions/get_user',{user_id:user_id});
	rr.user=rr.site.models.User.Get(user_id);
	var sid=this.mk_sid();
	if (!rr.fields["no-session"]) rr.site.sql.execute('sessions/insert',{sid: sid,user_id:user_id});
	var exp=undefined;
	var exprule=rr.site.auth?rr.site.auth.expires:undefined;
	var expdays=2;
	if (exprule) {
		switch (exprule.type) {
			case "days_plus":
				exp=new Date(new Date().getTime() + exprule.value*24*60*60*1000);
				expdays=Math.floor(exprule.value);
				break;
		}
	}
	if (!rr.fields["no-session"]) {
		//throw ["sid",sid,exp,'/',rr.site.cookie_domain];
		rr.res.cookie("sid",sid,exp,'/',rr.site.cookie_domain);
		rr.sid=sid;
	}
	this.load_roles(rr);
	if (rr.site.auth && rr.site.auth.onauth) rr.site.auth.onauth(rr);
	rr.site.sql.execute('sessions/delete_old',{days: expdays});
	//rr.site.sql.commit();
	return null;
}

/**
 * Method: logoff
 *		Performs user logoff
 *
 * Parameters:
 *		rr typeof LNRR - request-response object
 *
 * Returns:
 *		null
 */
LNSessions.prototype.logoff=function(rr) {
	rr.res.cookie("sid",'',undefined,'/',rr.site.cookie_domain);
	rr.sid="";
	return null;
}

/**
 * Method: cookie_auth
 *		Performs user auth by cookie
 *
 * Parameters:
 *		rr typeof LNRR - request-response object
 *
 * Returns:
 *		Error code or null
 */
LNSessions.prototype.cookie_auth=function(rr) {
	var sid=rr.req.cookie.sid;
	if (!sid) sid=rr.fields.sid;
	if (!sid && rr.req.get) sid=rr.req.get.sid;
	if (!sid) return undefined;
	//rr.user=rr.site.sql.execute_and_fetch_one('sessions/get_user_by_session',{sid: sid});
	rr.user=rr.site.models.User.Get("get_by_session",{sid:sid});
	if (!rr.user || rr.user.enabled==0) {
		rr.user={};
		return "Wrong cookie";
	}
	if (rr.user.date_last_page_needs_update) rr.site.sql.execute('sessions/update_date_last_page',rr.user);
	if (rr.user.date_exp_needs_update) rr.site.sql.execute('sessions/update_date_exp',rr.user);
	rr.site.sql.commit();
	rr.uid=rr.user.id;
	rr.sid=sid;
	this.load_roles(rr);
	return undefined;

}

/**
 * Method: work
 *		Performs authentication and authorization of user, tracks session
 *
 * Parameters:
 *		rr typeof LNRR - request-response object
 *
 * Returns:
 *		Error code string or null
 */
LNSessions.prototype.work=function(rr) {
	if (rr.fields['do-login']) {
		return this.login_auth(rr);

	} else if (rr.fields['do-logoff']) {
		return this.logoff(rr);
	}

	return this.cookie_auth(rr);
}

exports.LNSessions=LNSessions;
